package com.cqgc.service.impl;

import com.cqgc.exception.DeletionNotAllowedException;
import com.cqgc.exception.OrderCreateFailException;
import com.cqgc.exception.OrderUpdateFailException;
import com.cqgc.mapper.GoodsMapper;
import com.cqgc.mapper.OrderMapper;
import com.cqgc.mapper.UserMapper;
import com.cqgc.pojo.dto.OrderDTO.OrderDTO;
import com.cqgc.pojo.dto.OrderDTO.OrderQueryDTO;
import com.cqgc.pojo.dto.OrderDTO.OrderStatusDTO;
import com.cqgc.pojo.entity.*;
import com.cqgc.pojo.vo.ExportOrderVO;
import com.cqgc.pojo.vo.OrderDeliveryVO;
import com.cqgc.pojo.vo.OrderQuerySupplierVO;
import com.cqgc.pojo.vo.OrderQueryVO;
import com.cqgc.service.OrderService;
import com.cqgc.utils.ExcelUtil;
import com.cqgc.utils.ThreadLocalUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 添加订单
     * @param orderDTO
     */
    @Override
    @Transactional

    public void add(OrderDTO orderDTO) {

        //判断订单集合是否为空
        if (orderDTO.getOrderLists().size() == 0) {
            throw new OrderCreateFailException  ("订单不能为空");
        }
        //获取当前用户id
        Map<String,Object> map  = ThreadLocalUtil.get();
        Integer id = (Integer) map.get("uid");

        //生成订单号 时间戳13+用户id3+随机数4
        long timestamp = LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli();
        int randomNum = ThreadLocalRandom.current().nextInt(1000, 9999);
        String orderNumber = String.format("%d%03d%04d", timestamp, id, randomNum);

        ArrayList<Order> orders = new ArrayList<>();

        orderDTO.getOrderLists().forEach(orderList -> {
            if (orderList.getQuantity() <= 0) {
                throw new OrderCreateFailException("商品数量不能小于0");
            }
            Goods goods = goodsMapper.findById(orderList.getGid());
            if (goods == null) {
                throw new OrderCreateFailException("商品不存在");
            }
            // 检查库存
            if (orderList.getQuantity() > Integer.parseInt(goods.getAmount())) {
                throw new OrderCreateFailException(goods.getGoodsName()+"库存不足");
            }

            // 封装订单
            Order order = Order.builder()
                    .gid(orderList.getGid())
                    .orderNumber(orderNumber + orderList.getGid()) // 订单号+商品id
                    .quantity(orderList.getQuantity())
                    .providerId(goods.getCreateUser())
                    .consumerId(id)
                    .goodsName(goods.getGoodsName())
                    .address(orderDTO.getAddress())
                    .createTime(LocalDateTime.now())
                    .updateTime(LocalDateTime.now())
                    .status(1) // 未支付
                    .totalPrice(orderList.getQuantity() * goods.getPrice())
                    .build();
            orders.add(order);
            log.info("订单编号：{}",orderNumber);
            //发送消息//            rabbitTemplate.convertAndSend("order_queue",orderNumber+order.getGid());


            // 修改商品库存
            Integer amount = Integer.parseInt(goods.getAmount()) - order.getQuantity();
            goods.setAmount(String.valueOf(amount));
            goodsMapper.update(goods);
        });
        //新增订单
        orderMapper.add(orders);
    }



    /**
     * 修改订单状态
     * @param orderStatusDTO
     */
    @Transactional
    @Override
    public void updateStatus(OrderStatusDTO orderStatusDTO) {
        //判断订单是否存在
        if (orderMapper.findById(orderStatusDTO.getOrderNumber()) == null) {
            throw new OrderUpdateFailException("订单不存在");
        }
        //查询该订单的信息
        Order order = orderMapper.findById(orderStatusDTO.getOrderNumber());
        order.setStatus(orderStatusDTO.getStatus());
        //更改商品数量
        //1.查询出订单中购买的商品
        Goods goods = goodsMapper.findById(order.getGid());
        //2.获取该商品数量
        String amount = goods.getAmount();
        //3.该商品数量-订单中的商品数量
        amount = String.valueOf(Integer.parseInt(amount) + order.getQuantity());
        //修改该商品的库存

        Goods goods1 = new Goods();
        goods1.setAmount(amount);
        goods1.setGid(order.getGid());
        //订单取消，恢复库存
        if (order.getStatus() == 3){
            //修改商品数量
            goodsMapper.update(goods1);
        }
        //修改订单状态 0:已支付 1:未支付 2:已完成 3:已取消
        orderMapper.updateStatus(order);

    }

    /**
     * 查看订单
     * @return
     */


    /**
     * 通过订单编号删除订单
     * @param orderNumber
     */
    @Override
    public void deleteByOrderNumber(String orderNumber) {

        if (orderNumber == null){
            throw new DeletionNotAllowedException("订单编号不能为空");
        }
        //根据订单编号查询订单订单状态
        Order order = orderMapper.findById(orderNumber);
        int status = order.getStatus();
        //未支付订单不能删除
        if (status == 1){
            throw new DeletionNotAllowedException("订单未支付，只能取消，不能删除");
        }
        //已支付但还未完成订单不能删除
        else if (status == 0){
            throw new DeletionNotAllowedException("订单还未完成，不能删除");
        }
        //已完成订单对用户隐藏
        else if (status == 2){
            order.setStatus(4);
            orderMapper.updateStatus(order);
        }
        orderMapper.deleteByOrderNumber(orderNumber);
    }



    @Override
    public PageResult findByConditionPurchaser(OrderQueryDTO orderQueryDTO) {
        // 获取用户id
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer id = (Integer) map.get("uid");


        // 开启分页
        PageHelper.startPage(orderQueryDTO.getPageNum(), orderQueryDTO.getPageSize());

        OrderQuery orderQuery = new OrderQuery();
        BeanUtils.copyProperties(orderQueryDTO, orderQuery);
        orderQuery.setId(id);

        // 执行分页查询
        Page<Order> orderPage = (Page<Order>) orderMapper.findByCondition(orderQuery);

        // 创建一个用于存储转换后的OrderQueryVO的列表
        List<OrderQueryVO> orderQueryVOs = new ArrayList<>();

        // 遍历订单列表，转换为OrderQueryVO并设置供应商名称
        for (Order order : orderPage) {
            OrderQueryVO orderQueryVO = new OrderQueryVO();
            BeanUtils.copyProperties(order, orderQueryVO);

            // 假设一个订单只对应一个供应商，直接获取第一个
            User provider = userMapper.findById(order.getProviderId()).stream().findFirst().orElse(null);
            if (provider != null) {
                orderQueryVO.setProviderName(provider.getNickName());
            }

            orderQueryVOs.add(orderQueryVO);
        }

        // 返回分页结果，包含总记录数和转换后的数据列表
        return new PageResult(orderPage.getTotal(), orderQueryVOs);
    }



    @Override
    public PageResult findByConditionSupplier(OrderQueryDTO orderQueryDTO) {
        // 获取用户id
        Map<String, Object> map = ThreadLocalUtil.get();
        Integer id = (Integer) map.get("uid");


        // 开启分页
        PageHelper.startPage(orderQueryDTO.getPageNum(), orderQueryDTO.getPageSize());

        OrderQuery orderQuery = new OrderQuery();
        BeanUtils.copyProperties(orderQueryDTO, orderQuery);
        orderQuery.setId(id);

        // 执行分页查询
        Page<Order> orderPage = (Page<Order>) orderMapper.findByConditionSupplier(orderQuery);

        // 创建一个用于存储转换后的OrderQueryVO的列表
        List<OrderQuerySupplierVO> orderQueryVOs = new ArrayList<>();

        // 遍历订单列表，转换为OrderQueryVO并设置供应商名称
        for (Order order : orderPage) {
            OrderQuerySupplierVO orderQueryVO = new OrderQuerySupplierVO();
            BeanUtils.copyProperties(order, orderQueryVO);

            // 假设一个订单只对应一个供应商，直接获取第一个
            User consumer = userMapper.findById(order.getProviderId()).stream().findFirst().orElse(null);
            if (consumer != null) {
                orderQueryVO.setConsumerName(consumer.getNickName());
            }

            orderQueryVOs.add(orderQueryVO);
        }

        // 返回分页结果，包含总记录数和转换后的数据列表
        return new PageResult(orderPage.getTotal(), orderQueryVOs);
    }

    @Override
    public byte[] generateExcel(Integer status) {
        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            Map<String, Object> map = ThreadLocalUtil.get();
            Integer providerId = (Integer) map.get("uid");

            List<ExportOrderVO> exportOrderVOs = orderMapper.findByProviderId(providerId, status).stream()
                    .map(order -> {
                        ExportOrderVO orderVO = new ExportOrderVO();
                        BeanUtils.copyProperties(order, orderVO);

                        // 根据 consumerId 查询 consumerName
                        List<User> users = userMapper.findById(order.getConsumerId());
                        if (!users.isEmpty()) {
                            orderVO.setConsumerName(users.get(0).getNickName()); // 假设只取第一个用户
                        }
                        return orderVO;
                    })
                    .collect(Collectors.toList());

            // 更新调用，传入工作表名称
            ExcelUtil.exportDataWithEasyExcel(outputStream, "Orders", exportOrderVOs, ExportOrderVO.class);

            return outputStream.toByteArray();
        } catch (IOException e) {
            // 处理异常，可能需要记录日志或抛出自定义异常
            log.error("Failed to generate Excel", e);
            throw new RuntimeException("Failed to generate Excel", e);
        }
    }

    @Override
    public PageResult findByOrderStatus(int pageNum, int pageSize) {
        int status = 0;
        PageHelper.startPage(pageNum, pageSize);
        Page<OrderDeliveryVO> orderDeliveryVOS = orderMapper.findByOrderStatus(status);
//        Page<Order> orderLists = (Page<Order>) orderMapper.findByOrderStatus(status);
//
//
//        List<OrderDeliveryVO> orderDeliveryVOs = new ArrayList<>();
//
//        orderLists.stream().map(order -> {
//            OrderDeliveryVO orderDeliveryVO = new OrderDeliveryVO();
//            BeanUtils.copyProperties(order,orderDeliveryVO);
//            //消费者名称
//            String consumerName = userMapper.findByUser(order.getConsumerId()).getNickName();
//            //供应商名称
//            String providerName = userMapper.findByUser(order.getProviderId()).getNickName();
//            orderDeliveryVO.setConsumerName(consumerName);
//            orderDeliveryVO.setProviderName(providerName);
//            orderDeliveryVOs.add(orderDeliveryVO);
//            return null;
//        }).collect(Collectors.toList());
        return new PageResult(orderDeliveryVOS.getTotal(),orderDeliveryVOS.getResult());
    }


    /**
     * 修改订单
     * @param order
     */
    @Transactional
    @Override
    public void updateOrder(Order order) {

        //判断订单是否为空
        if (order == null){
            throw new OrderUpdateFailException("订单不能为空");
        }
        //查询订单详细信息
        Order orderQuery = orderMapper.findById(order.getOrderNumber());

        //判断订单此时的状态能否被修改
        int status = orderQuery.getStatus();
        if (! (status ==1 || status == 0)){
            throw new OrderUpdateFailException("订单修改失败");
        }

        //设置修改的地址
        order.setAddress(order.getAddress());
        order.setUpdateTime(LocalDateTime.now());

        if (status ==0){
            orderMapper.updateOrder(order);
        }

        if (status == 1){
            //获取用户修改的商品数量
            int quantity = order.getQuantity();
            //通过order中的orderNumber查询出该订单

            //获取订单中的商品数量
            int orderQuantity = orderQuery.getQuantity();
            //根据order中的orderNumber查询该商品的库存
            Goods goods = goodsMapper.findById(orderQuery.getGid());
            int amount = Integer.parseInt(goods.getAmount());
            //判断用户修改的数量是否大于订单中的数量
            if(quantity>amount){
                throw new OrderUpdateFailException("库存不足");
            }

            //设置订单中的商品数量
            order.setQuantity(quantity);
            //设置订单中的商品总价
            order.setTotalPrice(quantity * goods.getPrice());

            //修改订单
            orderMapper.updateOrder(order);
            //设置货物库存数量=商品库存+（订单中的数量-用户修改的数量)
            goods.setAmount(String.valueOf(amount + (orderQuantity-quantity)));

            //修改商品库存

            goodsMapper.update(goods);
        }



    }


}
